﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using Sharp.DataTransferObject;
using Sharp.Domain.PlatformBoundedContext.MasterDataModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.MasterDataModule.Services;
using Sharp.Domain.Model;
using Sharp.Domain.PlatformBoundedContext.PersonModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.PlatformModule.Aggregates;
using Sharp.Domain.Repositories;
using Sharp.Infrastructure;
using Sharp.Infrastructure.Crosscutting;
using Sharp.Infrastructure.IoC;
using Sharp.Infrastructure.Search;
using Sharp.ServiceContracts;

namespace Sharp.Application.Platform
{

    /// <summary>
    /// 系统支持服务
    /// </summary>
    public class SystemServiceImpl : ApplicationService, ISystemService
    {

        #region 构造函数


        /// <summary>
        ///     初始化一个新的<c>SystemServiceImpl</c>实例。
        /// </summary>
        /// <param name="context"></param>
        public SystemServiceImpl(IRepositoryContext context)
            : base(context)
        {
        }

        #endregion

        #region 主数据
        #region 保存主数据

        /// <summary>
        /// 保存主数据
        /// </summary>
        /// <param name="masterData">主数据</param>
        /// <returns>操作结果</returns>
        [Logging("保存主数据“{@p0.Name}”")]
        public Result SaveMasterData<TMasterData>(TMasterData masterData)
            where TMasterData : class, IAggregateRoot, IMasterData, new()
        {
            Result res = new Result();
            var masterDataRepository = ServiceLocator.Instance.GetService<IMasterDataRepository<TMasterData>>();
            if (masterData.Id.IsEmpty())
            {
                masterDataRepository.Add(masterData);
            }
            else
            {
                var info = masterDataRepository.Get(masterData.Id);
                info.Name = masterData.Name;
                info.FullName = masterData.FullName;
                info.Code = masterData.Code;
                info.ParentCode = masterData.ParentCode;

                masterDataRepository.Update(info);
            }
            Context.Commit();

            CacheHelper.Remove("GetMasterData_" + typeof(TMasterData).Name);

            return res;
        }

        #endregion

        #region 删除主数据

        /// <summary>
        /// 删除主数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Logging("删除主数据“{@p0}”")]
        public Result DeleteMasterData<TMasterData>(Guid[] ids) where TMasterData : class, IAggregateRoot, IMasterData, new()
        {
            var res = new Result();
            if (ids == null)
            {
                res.Err = "Id参数不可为空！";
                return res;
            }
            var service = ServiceLocator.Instance.GetService<IMasterDataService<TMasterData>>();
            res = service.DeleteMasterData(ids);

            CacheHelper.Remove("GetMasterData_" + typeof(TMasterData).Name);

            return res;
        }

        #endregion

        #region 获取一条主数据

        /// <summary>
        /// 获取一条主数据
        /// </summary>
        /// <returns></returns>
        public TMasterData GetMasterDataInfo<TMasterData>(Guid id)
            where TMasterData : class, IAggregateRoot, IMasterData, new()
        {
            var masterDataRepository = ServiceLocator.Instance.GetService<IMasterDataRepository<TMasterData>>();
            return masterDataRepository.Get(id);
        }

        #endregion

        #region 获取主数据

        /// <summary>
        /// 获取主数据
        /// </summary>
        /// <returns></returns>
        public IList<TMasterData> GetMasterData<TMasterData>()
            where TMasterData : class, IAggregateRoot, IMasterData, new()
        {
            List<TMasterData> data;
            if (CacheHelper.TryGet("GetMasterData_" + typeof(TMasterData).Name, out data))
            {
                return data;
            }
            var masterDataRepository = ServiceLocator.Instance.GetService<IMasterDataRepository<TMasterData>>();
            data = masterDataRepository.GetList(null, "Code ASC", (int?)null, new string[] { }).ToList();
            if (data.Any())
            {
                CacheHelper.Add("GetMasterData_" + typeof(TMasterData).Name, data, 3600);
            }
            return data;
        }

        #endregion

        #region 代码项翻译成文字项

        /// <summary>
        /// 代码项翻译成文字项
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public string Code2Text<TMasterData>(string code)
            where TMasterData : class, IAggregateRoot, IMasterData, new()
        {
            var service = ServiceLocator.Instance.GetService<IMasterDataService<TMasterData>>();
            return service.Code2Text(code);
        }

        #endregion

        #region 获取主数据分类

        /// <summary>
        /// 获取主数据分类
        /// </summary>
        /// <returns></returns>
        public IList<MasterData> GetMasterDataSort()
        {
            string bin = WebServer.MapPath("~/bin/");

            List<MasterData> masterDataSorts = new List<MasterData>();
            //动态加载组件dll
            foreach (var dllName in new DirectoryInfo(bin).GetFiles("*.dll"))
            {
                Assembly ass;
                try
                {
                    ass = Assembly.LoadFrom(dllName.FullName);
                }
                catch
                {
                    continue;
                }

                string entryClass;

                try
                {
                    entryClass = ass.GetTypes()
                        .Where(
                            x =>
                                x.IsClass && ass.GetReferencedAssemblies().Any(y => y.FullName.Contains("Sharp.Domain")))
                        .Select(x => x.FullName)
                        .FirstOrDefault();
                }
                catch
                {
                    continue;
                }

                if (entryClass == null)
                {
                    continue;
                }

                Type[] types;
                try
                {
                    types = ass.GetTypes();
                }
                catch
                {
                    continue;
                }

                foreach (Type type in types)
                {
                    if (type.Name == "MasterData")
                    {
                        continue;
                    }
                    if (type.GetInterface("IMasterData") == null)
                    {
                        continue;
                    }
                    var category = (type.GetCustomAttribute(typeof(CategoryAttribute)) as CategoryAttribute);
                    var strcategory = category == null ? "未分类" : category.Category;

                    if (masterDataSorts.All(x => x.Name != strcategory))
                    {
                        masterDataSorts.Add(new MasterData
                        {
                            Id = Guid.NewGuid(),
                            Name = strcategory,
                            FullName = "",
                            Code = strcategory,
                            ParentCode = null
                        });
                    }
                    var description = type.GetCustomAttribute(typeof(DescriptionAttribute)) as DescriptionAttribute;
                    var dto = new MasterData
                    {
                        Id = type.GUID,
                        Name = description == null ? type.Name : description.Description,
                        FullName = type.AssemblyQualifiedName,
                        Code = type.Name,
                        ParentCode = strcategory
                    };

                    masterDataSorts.Add(dto);
                }

            }
            return masterDataSorts;
        }
        #endregion

        #region 获取分页数据

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageno"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        public PagedResult<MasterDataDTO> GetPaged<TMasterData>(int pageno, int pagesize)
            where TMasterData : class, IAggregateRoot, IMasterData, new()
        {
            var masterDataRepository = ServiceLocator.Instance.GetService<IMasterDataRepository<TMasterData>>();
            var paged = masterDataRepository.Pagging(pageno, pagesize, "Code ASC");

            return paged.To<TMasterData, MasterDataDTO>();
        }

        #endregion

        #endregion

        #region 获取省份数据
        /// <summary>
        /// 获取省份数据
        /// </summary>
        /// <returns></returns>
        public IList<AdministrativeDivision> GetProvinceData()
        {
            var proxy = ServiceLocator.Instance.GetService<IMasterDataRepository<AdministrativeDivision>>();
            return proxy
                .GetList(x => x.ParentCode == null, "Code ASC", null, new string[] { })
                .Select(x => new AdministrativeDivision()
                {
                    Id = x.Id,
                    Name = x.Name,
                    FullName = x.FullName,
                    Code = x.Code.Substring(0, 3),
                    ParentCode = x.ParentCode
                }).ToList();
        }
        #endregion

        
    }
}
